/**
 * 工具方法
 */

import dayjs from 'dayjs';
import { Message } from '@teamix/ui';
import CONSTANTS from 'utils/constants';
import { getFeature } from 'utils/features';
import * as _events from './events';
import intl from '../locale';

const { locale } = window.FORCE;
const { ENUM } = CONSTANTS;

const tools = {
  getAdminSettingLanguage(admin_setting_language) {
    let template = 'view';
    switch (admin_setting_language) {
      case 'Python':
        template = 'python';
        break;
      case 'JavaScript':
      case 'TypeScript':
        template = 'node';
        break;
      case 'Java':
        template = getFeature('WebIDE.getAdminSettingLanguage.java');
        break;
      case 'Golang':
        template = 'go';
        break;
      case 'Ruby':
        template = 'ruby';
        break;
      case 'Cpp':
        template = 'cpp';
        break;
      case 'Rust':
        template = 'rust';
        break;
      default:
        break;
    }
    return template;
  },
  // 获取url中的参数
  getUrlParam({ name, type }) {
    const reg = new RegExp(`(^|&)${name}=([^&]*)(&|$)`);
    const r = decodeURIComponent(window.location[`${type}`].substr(1)).match(reg);
    if (r != null) return unescape(r[2]);
    return null;
  },
  // 获取url中的search参数
  getUrlSearchParam(name) {
    return tools.getUrlParam({ name, type: 'search' });
  },
  // Compare页面参数解码
  getUrlSearchParamByComparePage(name) {
    const reg = new RegExp(`(^|&)${name}=([^&]*)(&|$)`);
    const r = window.location.search.substr(1).match(reg);
    if (r != null) return unescape(r[2]);
    return null;
  },
  // 获取url中的hash参数
  getUrlHashParam(name) {
    return tools.getUrlParam({ name, type: 'hash' });
  },
  // 构造redux action的namespace
  namespace(name) {
    return function (v) {
      return `${name}-${v}`;
    };
  },
  // 获得简化的时间-for过去的时间
  getBeautyTime(originalTime, lang = locale, type = 'normal') {
    function i18n(cn, en) {
      return lang === 'en_US' ? en : cn;
    }

    const timeDuring = new Date() - new Date(originalTime);
    const todayDate = dayjs(new Date()).format('YYMMDD');
    const originalTimeDate = dayjs(originalTime).format('YYMMDD');
    const curYear = dayjs(new Date()).format('YYYY');
    const originalYear = dayjs(originalTime).format('YYYY');
    let brifeTime;
    if (timeDuring < 60 * 1000) {
      if (parseInt(timeDuring / 1000) < 5) {
        brifeTime = intl.get({ id: 'code-assets.src.utils.Now', defaultMessage: '现在' });
      } else {
        const time = parseInt(timeDuring / 1000);
        brifeTime = `${time}${i18n(' 秒前', ' seconds ago')}`;
      }
    } else if (timeDuring < 60 * 60 * 1000) {
      const time = parseInt(timeDuring / 60 / 1000);
      brifeTime = `${time}${i18n(' 分钟前', ' minutes ago')}`;
    } else if (originalTimeDate === todayDate) {
      brifeTime =
        intl.get({ id: 'code-assets.src.utils.Today', defaultMessage: '今天' }) +
        dayjs(originalTime).format('HH:mm');
    } else if (Number(originalTimeDate) === todayDate - 1) {
      brifeTime =
        intl.get({ id: 'code-assets.src.utils.Yesterday', defaultMessage: '昨天' }) +
        dayjs(originalTime).format('HH:mm');
    } else if (curYear === originalYear) {
      brifeTime =
        type !== 'simple'
          ? dayjs(originalTime).format('MM月DD日 HH:mm')
          : dayjs(originalTime).format('MM月DD日');
    } else {
      brifeTime =
        type !== 'simple'
          ? dayjs(originalTime).format('YYYY年MM月DD日 HH:mm')
          : dayjs(originalTime).format('YYYY年MM月DD日');
    }
    return brifeTime;
  },
  // 判断传入的时间是否距当前一小时内，用于如 commit at 是否需要有 at 的判断
  isInOneHour(time) {
    const timeDuring = new Date() - new Date(time);
    return timeDuring < 1000 * 60 * 60 * 60;
  },
  // 设置localStorage
  setCachedData(key, value) {
    const { localStorage } = window;
    if (!localStorage) {
      Message.success({
        title:
          'Your browser version is too low, please upgrade or use a more advanced browser like chrome',
      });

      return false;
    }

    localStorage.setItem(key, value);
  },
  // 读取localStorage
  getCachedData(key) {
    const { localStorage } = window;
    if (!localStorage) {
      Message.success({
        title:
          'Your browser version is too low, please upgrade or use a more advanced browser like chrome',
      });

      return false;
    }

    return localStorage.getItem(key);
  },
  // 判断文件是否是readme
  isReadme(name) {
    if (!name) {
      return false;
    }

    // 后缀>无后缀，大小写没有区别，取数组的第一个。后缀：.mdown .mkd .mkdn .md .markdown
    return name.toLowerCase().indexOf('readme') !== -1;
  },
  // 判断文件是否是markdown
  isMarkdown(name) {
    if (!name) {
      return false;
    }

    // 后缀为：.mdown .mkd .mkdn .md .markdown
    return /\.md|\.markdown|\.mdown|\.mkd|\.mkdn|\.MD|\.MARKDOWN|\.MDOWN|\.MKD|\.MKDN$/.test(name);
  },
  // ipynb
  isIpynb(name) {
    if (!name) {
      return false;
    }
    return /\.ipynb|\.IPYNB$/.test(name);
  },
  // json字符串
  isJSON(str) {
    if (typeof str === 'string') {
      try {
        const obj = JSON.parse(str);
        if (typeof obj === 'object' && obj) {
          return true;
        } else {
          return false;
        }
      } catch (e) {
        return false;
      }
    }
    return false;
  },
  /**
   * 处理project/namespace的visibility level
   * 之前存在PRIVATE(0),INTERNAL(10)和PUBLIC(20)这三个值
   * 改版之后只保留PRIVATE和INTERNAL
   * 因此需要把PUBLIC映射到INTERNAL
   * @param originalValue
   */
  processVisibilityLevel(originalValue) {
    if (originalValue === ENUM.visibility_level.PUBLIC) {
      return ENUM.visibility_level.INTERNAL;
    }
    return originalValue;
  },
  // 由 visibility_levels 数字换取文案
  getVisibilityLevelsText(level) {
    let label = '';
    ENUM.visibility_levels.forEach((item) => {
      if (item.value === Number(level)) {
        label = item.label;
      }
    });
    return label;
  },
  /**
   * name_with_namespace格式：xx / xxx / xxx
   * name为最后一个/之后的部分（去除空格）
   */
  getNameFromNameWithNamespace(nameWithNamespace) {
    if (nameWithNamespace) {
      const match = nameWithNamespace.match('.*/ *(.*)');
      if (match && match.length === 2) {
        return match[1];
      }
    }
    return nameWithNamespace;
  },
  /**
   * path_with_namespace格式：xx / xxx / xxx
   * path为最后一个/之后的部分（去除空格）
   */
  getPathFromPathWithNamespace(pathWithNamespace) {
    if (pathWithNamespace) {
      const match = pathWithNamespace.match('.*/(.*)');
      if (match && match.length === 2) {
        return match[1];
      }
    }
    return pathWithNamespace;
  },
  /**
   * nickname > username > email_prifex
   * @param {*} username
   * @param {*} nickname
   * @param {*} email
   */
  getUserDisplayName(username, nickname, email) {
    return nickname || username || (/.*@.*/.test(email) ? email.split('@')[0] : '');
  },
  /**
   * 判断文件名是否是图片后缀
   */
  isImageSuffix(fileName) {
    return /\.(png|jpg|jpeg|gif|PNG|JPG|JPEG|GIF)$/.test(fileName);
  },
  /**
   * Display short SHA
   */
  showShortSha(sha) {
    return sha ? sha.substr(0, 8) : sha;
  },
  /**
   * 路径转为树结构
   * extraKey: 额外需要增加的字段
   * 由:
   * /a/b/c/d/e
   * /a/b/e/f/g
   * /a/b/h
   * /a/i/j
   * /a/i/k
   * 转为:
         a
       /   \
      b     i
     /|\   / \
    c e h j   k
    | |
    d f
    | |
    e g
   */
  transferPath2Tree(arr, extraKey) {
    const rtree = [];
    arr.forEach((item) => {
      const { path: key } = item; // key is the full path
      const uri = key.split('/'); // split the full path with '/'
      let uri_pt = rtree;
      let path = '';
      if (uri_pt.length == 0) {
        const root = {
          key: `${path}/${uri[1]}`,
          title: uri[1],
        };

        if (extraKey) {
          root[extraKey] = item[extraKey];
        }
        if (uri.length > 2) {
          root.children = [];
        }
        uri_pt.push(root);
      }
      for (const i in uri) {
        if (i == 0) continue;
        path += `/${uri[i]}`;
        const treeitem = {
          key: path,
          title: uri[i],
        };

        if (extraKey) {
          treeitem[extraKey] = item[extraKey];
        }
        if (i != uri.length - 1) {
          treeitem.children = [];
        }
        if (uri_pt.length == 0) {
          uri_pt.push(treeitem);
        }
        let isExist = false;
        for (const j in uri_pt) {
          if (uri_pt[j].key == treeitem.key) {
            if (i != uri.length - 1 && !uri_pt[j].children) {
              uri_pt[j].children = [];
            }
            uri_pt = i == uri.length - 1 ? uri_pt : uri_pt[j].children;
            isExist = true;
            break;
          }
        }
        if (!isExist) {
          uri_pt.push(treeitem);
          if (i != uri.length - 1 && !uri_pt[uri_pt.length - 1].children) {
            uri_pt[uri_pt.length - 1].children = [];
          }
          uri_pt = i == uri.length - 1 ? uri_pt : uri_pt[uri_pt.length - 1].children;
        }
      }
    });
    function addKeys(data) {
      data.forEach((item) => {
        item.id = item.key.slice(1);
        item.name = item.title;
        item.type = item.children ? 'tree' : 'blob';
        if (item.children) {
          addKeys(item.children);
        }
      });
    }
    addKeys(rtree);
    return rtree;
  },
  // 组显示路径是要去除第一个组织id
  getGroupPath(path) {
    const arr = path.split('/');
    const newArr = arr.slice(1);
    return newArr.join('/').trim();
  },
  // 对跳转链接或get接口参数中的 revision（分支或tag）做 encodeURIComponent
  revisionEncodeURI(revision) {
    if (!revision) {
      return '';
    }

    // const result = revision.replace(/%/g, '%25').replace(/#/g, '%23');
    // const result = revision.replace(/#/g, '%23');
    const result = encodeURIComponent(revision);
    return result;
  },
  // 对跳转链接中的 filepath 做 encodeURIComponent
  filepathEncodeURI(filepath) {
    if (!filepath) {
      return '';
    }
    // 现在空格不需要转义
    // const reg = new RegExp('\\s', 'g');
    // const result = filepath.replace(reg, '%20');
    return filepath;
  },
  // 兼容旧数据
  getCompatibleSettingData(repo_creator_identity) {
    let cur_repo_creator_identity = repo_creator_identity;
    // 未开启代码组开启时增加接口兼容，原有[0]为[15,60](限制了外部成员不能创建库),原有1为[5,15,60];
    if (repo_creator_identity[0] === 0) {
      cur_repo_creator_identity = [15, 60];
    } else if (repo_creator_identity[0] === 1) {
      cur_repo_creator_identity = [5, 15, 60];
    }
    return cur_repo_creator_identity;
  },
  // 企业设置是否允许创建库（兼容多级组+老版本）
  allowCreateRepo(repoCreatorIdentity, role) {
    if (!repoCreatorIdentity) {
      return false;
    }

    const curUserRoleLevel = CONSTANTS.ENUM.org_role_access_level[role];

    if (curUserRoleLevel >= CONSTANTS.ENUM.org_role_access_level.ORG_ADMIN) {
      return true;
    }

    for (let i = 0; i < repoCreatorIdentity.length; i++) {
      const identity = repoCreatorIdentity[i];
      // 兼容老的配置
      if (identity === 1) {
        return true;
      }

      if (identity === 0) {
        return role !== 'ORG_EXTERNAL_MEMBER';
      }

      // 多级组配置
      if (identity === curUserRoleLevel) {
        return true;
      }
    }
    return false;
  },
  // 解析cookie
  parseCookie: (cookie) => {
    const cookies = {};
    if (!cookie) {
      return cookies;
    }
    const list = cookie.split(';');
    for (let i = 0; i < list.length; i++) {
      const pair = list[i].split('=');
      cookies[pair[0].trim()] = pair[1];
    }
    return cookies;
  },
  endsWith(str, suffix) {
    return str.indexOf(suffix, str.length - suffix.length) !== -1;
  },
  setCache(key, val, parse = true) {
    let value = val;
    if (parse) {
      value = JSON.stringify(val);
    }
    window.localStorage.setItem(key, value);
  },
  getCache(key, parse = true) {
    const cache = window.localStorage.getItem(key);
    if (!cache) return '';
    if (!parse) return cache;
    return JSON.parse(cache);
  },
  getCookie(key) {
    const cookies = document.cookie.split('; ');
    let value = null;
    cookies.forEach((cookie) => {
      const kv = cookie.split('=');
      if (key === kv[0]) {
        value = kv[1];
      }
    });
    return value;
  },
  setCookie(key, value, expire) {
    const d = new Date();
    d.setTime(d.getTime() + expire);
    document.cookie = `${key}=${value}; Expires=${d.toUTCString()}; path=/; Domain=aliyun.com`;
  },
  getListFromLike(listLike) {
    if (!listLike) {
      return;
    }
    const list = [];
    for (let i = 0, len = listLike.length; i < len; i++) {
      list.push(listLike[i]);
    }
    return list;
  },
  getWindowInfo() {
    return {
      winW: window.innerWidth,
      winH: window.innerHeight,
    };
  },
  offset(obj, direction) {
    // 将top,left首字母大写,并拼接成offsetTop,offsetLeft
    const offsetDir = `offset${direction[0].toUpperCase()}${direction.substring(1)}`;

    let realNum = obj[offsetDir];
    // 获取上一级定位元素对象
    let positionParent = obj.offsetParent;

    // let lastPosition;
    while (positionParent != null && positionParent.classList[0] !== 'guide-container') {
      realNum += positionParent[offsetDir];
      positionParent = positionParent.offsetParent;
    }

    return realNum;
  },
  getParentUrl() {
    let url = '';
    if (parent !== window) {
      try {
        url = parent.location.href;
      } catch (e) {
        url = document.referrer;
      }
    }
    return url;
  },
  getUrlHost() {
    return `${window.location.protocol}//${window.location.host}`;
  },
  formatSecondToDate(second) {
    const min = Math.floor(second / 60);
    const day = Math.floor(min / 8 / 60);
    const hour = Math.floor((min - day * 8 * 60) / 60);
    const minute = Math.floor(min - day * 8 * 60 - hour * 60);
    const units = ['d', 'h', 'min'];
    return (
      [day, hour, minute]
        .map((item, index) => (item ? item + units[index] : ''))
        .filter((i) => i)
        .slice(0, 2)
        .join(' ') || '0min'
    );
  },
  // repoSize 单位字节
  getSizeStr(repoSize) {
    let beautifulRepoSize = '';
    const repoSizeNum = Number(repoSize);
    if (!repoSize) {
      beautifulRepoSize = '';
    } else if (repoSizeNum < 1024) {
      beautifulRepoSize = `${repoSizeNum}B`;
    } else if (repoSizeNum < 1024 * 1024) {
      beautifulRepoSize = `${Math.ceil((repoSizeNum / 1024) * 100) / 100}K`;
    } else if (repoSizeNum < 1024 * 1024 * 1024) {
      beautifulRepoSize = `${Math.ceil((repoSizeNum / 1024 / 1024) * 100) / 100}M`;
    } else {
      beautifulRepoSize = `${Math.ceil((repoSizeNum / 1024 / 1024 / 1024) * 100) / 100}G`;
    }
    return beautifulRepoSize;
  },
  allowComments(curCommentsNumber = 0, commentConfig = {}) {
    const { limit_comment = false, limit_comments_number = 50 } = commentConfig;
    if (limit_comment) {
      return curCommentsNumber < limit_comments_number;
    }
    return true;
  },
  // 将零散的评论组织成回复模式
  comments2Conversations(data) {
    const conversations = [];
    data.forEach((comment) => {
      // 云豆回复的issue存在将issue处理为第一个根评论
      const isRoot = !comment.parent_note_id && !comment.issue;
      const isInConversations = conversations.some((item) => {
        return (
          item[0] && item[0].issue_id === comment.issue_id && item[0]._comment_type === 'issue'
        );
      });
      if (isRoot) {
        conversations.push([comment]);
      } else if (!comment.parent_note_id && comment.issue && !isInConversations) {
        const curComment = JSON.parse(JSON.stringify(comment));
        delete curComment.author;
        conversations.push([
          {
            ...curComment,
            author: {
              name: intl.get({ id: 'code-assets.src.utils.KidneyBeans', defaultMessage: '云豆' }),
              avatar_url: 'https://img.alicdn.com/tfs/TB1WYSpIQL0gK0jSZFtXXXQCXXa-400-401.png',
            },

            outdated: comment.issue.status && comment.issue.status.toLowerCase() === 'resolved',
            created_at: comment.issue.intro_time,
            path: comment.issue.file_name,
            line: comment.issue.begin_line,
            side: 'right',
            // 标识云豆检测结果
            _comment_type: 'issue',
          },
          comment,
        ]);
      } else if (isInConversations) {
        const curComment = conversations.find((item) => {
          return item[0] && item[0].issue_id === comment.issue_id;
        });
        curComment.push(comment);
      } else {
        conversations.forEach((conversation) => {
          conversation.forEach((childItem) => {
            if (childItem.id === comment.parent_note_id) {
              conversation.push(comment);
            }
          });
        });
      }
    });
    // 评论面板 简单按照文件排序
    const conversationsPathSort = conversations.sort((a, b) => {
      if (a[0].path && b[0].path && a[0].path !== b[0].path) {
        return a[0].path.localeCompare(b[0].path);
      } else {
        return 0;
      }
    });
    const openConversations = conversationsPathSort.filter((cvs) => {
      return cvs[0] && !cvs[0].closed;
    });
    return {
      conversations: conversationsPathSort,
      openConversations,
    };
  },
  // 目前只给仓库commits接口的ref_name参数用，根据revisionType不同，分支传递refs/heads/xx； tag 传递refs/tags/； commit 直接传 commit号
  getRevisionRef(revision, revisionType) {
    let ref;
    switch (revisionType) {
      case 'sha1':
        ref = revision;
        break;
      case 'tag':
        ref = `refs/tags/${revision}`;
        break;
      default:
        ref = `refs/heads/${revision}`;
        break;
    }
    return ref;
  },
  transformRelativePathToAbsolutePath(path, resourcePath) {
    // 检测形如![](Dingtalk_20210413103234.jpg)的路径, resourcePath = aa/b.md
    if (/^\[(.*?)\]\(https?:\/\/(.*?)\)$/.test(path)) {
      return path;
    }
    const arr = resourcePath.split('/');
    arr.pop();
    const add = arr.join('/');
    return path.replace(/^\[(.*?)\]\((.*?)\)$/, `[$1](${add}/$2)`);
  },
  isTooLarge(pathResource = {}) {
    const { repoSize, repoLimitSize, renewal_flag, plan_type, history_scale_repo } = pathResource;
    return (
      (plan_type === 'baseVersion' && history_scale_repo) ||
      renewal_flag ||
      Number(repoSize) >= Number(repoLimitSize || 2048) * 0.98
    );
  },
  isMirrorSynchronizing(status) {
    return status === 'READY' || status === 'SYNCHRONIZING';
  },
  isGenWatermarkimage(data) {
    if (data && data.contentType && data.waterMarkLink) {
      return `url(data:image/png;base64,${data.waterMarkLink})`;
    }
  },
  // changeState(state) {
  //   const newState = {};
  //   COMMON.forEach((item) => {
  //     if (state[item.key]) {
  //       item.value.forEach((v) => {
  //         if (!state[item.key][v] && state[item.key][`common_${v}`]) {
  //           if (newState[item.key] === undefined) {
  //             newState[item.key] = {};
  //           }
  //           newState[item.key][v] = state[item.key][`common_${v}`];
  //         }
  //       });
  //     }
  //   });
  //   return {
  //     root: state.root,
  //     organization: {
  //       ...state.organization,
  //       ...newState.organization,
  //     },
  //     project: {
  //       ...state.project,
  //       ...newState.project,
  //     },
  //     group: {
  //       ...state.group,
  //       ...newState.group,
  //     },
  //   };
  // },
  projectOrGroup: (pathResource) => {
    const isProject = pathResource && pathResource.type === 'PROJECT';
    const isGroup = pathResource && pathResource.type === 'GROUP';
    const isProjectOrGroup = isProject || isGroup;
    return { isProject, isGroup, isProjectOrGroup };
  },
};

export const NameSpace = tools.namespace.bind(tools);
export const events = _events;
export default tools;
